#ifndef CSV_HELPER_HPP
#define CSV_HELPER_HPP

#include <cstdint>
#include <string>
#include <vector>
#include <map>
#include <time.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <errno.h> 

namespace csv {

#if defined(WIN32)
inline int64_t atoll(const char *p) {
    int     minus = 0;
    int64_t value = 0;
    if (*p == '-') {
        minus++;
        p++;
    }
    while (*p >= '0' && *p <= '9') {
        value *= 10;
        value += *p - '0';
        p++;
    }
    return minus ? 0 - value : value;
}
#endif /* defined(WIN32) */
inline void split(const std::string& src, const std::string& delim, std::vector<std::string>& result) {
    size_t end   = 0;
    size_t begin = 0;
    while (end != std::string::npos) {
        end = src.find_first_of(delim, begin);
        if (end != std::string::npos) {
            result.push_back(src.substr(begin, end - begin));
        } else {
            result.push_back(src.substr(begin, std::string::npos));
        }
        begin = end + 1;
    }
}
inline std::string completePath(const std::string& path) {
#ifdef WIN32
    char seperator = '\\';
#else
    char seperator = '/';
#endif // WIN32
    if (path[path.size() - 1] != seperator) {
        return std::string(path + seperator);
    }
   return path;
}

inline bool checkCsvString(std::string& str) {
    auto length = str.length();
    if (length > 0 && str[length - 1] == '\r') {
        str.erase(str.end() - 1);
    }
    if (str.length() <= 0) {
        return false;
    }
    return true;
}

template<typename T>
class Singleton {
public:
    static T* instance();
    static void destroy();
protected:
    Singleton() {}
    virtual ~Singleton() {}
private:
        Singleton(const Singleton&) {}
        Singleton& operator=(const Singleton&) {}
private:
    static T* _instance;
};
template<typename T>
T* Singleton<T>::instance() {
    if (!_instance) {
        _instance = new T;
    }
    return _instance;
}
template<class T>
void Singleton<T>::destroy() {
    if (_instance) {
        delete _instance;
        _instance = 0;
    }
}
template<typename T> T* Singleton<T>::_instance = 0;



class ValueCast {
public:
    ValueCast(void* ptr = nullptr)
    : _ptr(ptr) {
    }

    ValueCast(const ValueCast& rht) {
        _ptr = rht._ptr;
    }

    ~ValueCast() {
    }

    const ValueCast& operator=(const ValueCast& rht) {
        _ptr = rht._ptr;
        return *this;
    }

    template <typename T>
    const T& castConst() const {
        return *((T*)_ptr);
    }
	
	template <typename T>
    T& cast() {
        return *((T*)_ptr);
    }

    operator bool() const {
        return (_ptr != nullptr);
    }

private:
    void* _ptr;
};

static ValueCast nullValueCast;

inline static time_t getModTime(const std::string& name) {
#ifndef WIN32
    struct stat st;
    memset(&st, 0, sizeof(st));
    if (lstat(name.c_str(), &st) < 0) {
        return 0;
    }
    return st.st_mtime;
#else
    struct _stat st;
    int result = _stat(name.c_str(), &st);
    if (result) {
        return 0;
    }
    return st.st_mtime;
#endif // WIN32
}

class CSVLoader {
public:
    virtual ~CSVLoader() {}
    virtual bool needReload() = 0;
    virtual bool load(const std::string& path) = 0;
};

}

#endif // CSV_HELPER_HPP
